﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Framework;
using SchemaMonitor;
using System.Data;

public partial class pages_photoHashs_Repeats : System.Web.UI.Page
{
    public Guid MD5 { get { return CWeb.RequestGuid("md5"); } }
    public Guid Delete { get { return CWeb.RequestGuid("delete"); } }
    public Guid Different { get { return CWeb.RequestGuid("different"); } }

    protected void Page_Init(object sender, EventArgs e)
	{
		//Different
		if (!Guid.Empty.Equals(MD5) && !Guid.Empty.Equals(Different))
		{
			var diff = new CImageMatching().SelectById(MD5, Different);
			diff.AddRange(new CImageMatching().SelectById(Different, MD5));
			foreach (var i in diff)
			{
				var x = new CImageMatchedButDifferent();
				x.MD5 = i.MD5;
				x.MatchingMd5 = i.MatchingMd5;
				x.Score = i.Score;
				x.Save();
				i.Delete();
			}

			Response.Redirect("repeats.aspx?md5=" + MD5.ToString(), true);
		}

		//Delete
        if (!Guid.Empty.Equals(MD5) && !Guid.Empty.Equals(Delete))
        {
            var d = CPhotoHash.Cache.GetById(Delete);
            var k = CPhotoHash.Cache.GetById(MD5);
            if (!string.IsNullOrEmpty(d.PhotoFileNames))
            {
                if (string.IsNullOrEmpty(k.PhotoFileNames))
                    k.PhotoFileNames = d.PhotoFileNames;
                else if (!k.PhotoFileNames.Contains(d.PhotoFileNames))
                    k.PhotoFileNames += "\r\n" + d.PhotoFileNames;
                k.Save();
            }
            if (!string.IsNullOrEmpty(d.PhotoCaptions))
            {
                if (string.IsNullOrEmpty(k.PhotoCaptions))
                    k.PhotoCaptions = d.PhotoCaptions;
                else if (!k.PhotoCaptions.Contains(d.PhotoCaptions))
                    k.PhotoCaptions += "\r\n\r\n" + d.PhotoCaptions;
                k.Save();
            }
            foreach (var i in d.MetaTags)
                if (!k.MetaTags.Contains(i))
                {
                    var lbl = new CLabel();
                    lbl.LabelGuid = k.PhotoMd5;
                    lbl.LabelTagId = i.TagId;
                    lbl.Save();
                }
            foreach (var i in d.MetaTagsO2O)
                if (!k.MetaTagsO2O.Contains(i))
                {
                    var lbl = new CLabel_OneToOne();
                    lbl.LabelGuid = k.PhotoMd5;
                    lbl.LabelTagId = i.TagId;
                    lbl.LabelTypeId = i.TagTypeId;
                    lbl.Save();
                }
            foreach (var i in d.ChapterPictures)
                if (!k.Chapters.Contains(i.Chapter))
                {
                    var c = new CChapterPicture();
                    c.PicturePhotoMD5 = k.PhotoMd5;
                    c.PictureChapterId = i.PictureChapterId;
                    c.PictureSortOrder = i.PictureSortOrder;
                    c.Save();
                }

            var sql1 = "UPDATE " + CImageMatching.TABLE_NAME + " SET MD5='" + MD5 + "' WHERE MD5='" + Delete + "'";
            var sql2 = "UPDATE " + CImageMatching.TABLE_NAME + " SET MatchingMD5='" + MD5 + "' WHERE MatchingMD5='" + Delete + "'";
            var sql3 = "DELETE FROM " + CImageMatching.TABLE_NAME + " WHERE MD5=MatchingMD5";
            var sql4 = "UPDATE " + CPhoto.TABLE_NAME + " SET Md5='" + MD5 + "' WHERE Md5 ='" + Delete + "'";
            var sql5 = "UPDATE " + CChapterPicture.TABLE_NAME + " SET PicturePhotoMD5='" + MD5 + "' WHERE PicturePhotoMD5 ='" + Delete + "'";
            

            try
			{
				CConfig.Photos.ExecuteNonQuery(sql1);
			}
			catch { }
			try
			{
				CConfig.Photos.ExecuteNonQuery(sql2);
			}
			catch { }
			try
			{
				CConfig.Photos.ExecuteNonQuery(sql3);
			}
			catch { }
			try
			{
				int x = CConfig.Photos.ExecuteNonQuery(sql4);
				if (x > 0)
					CPhoto.Cache = null;
				d.Delete();
			}
			catch
			{ }
            try
            {
                CDataSrc.Default.ExecuteNonQuery(sql5);
            }
            catch { }
            try
			{
				d.Delete();
			}
			catch
			{
				var im = new CImageMatching();
				var w = new CCriteriaList(EBoolOperator.Or);
				w.Add("MD5", Delete);
				w.Add("MatchingMd5", Delete);
				im.DeleteWhere(w);
			}

			Response.Redirect("repeats.aspx?md5=" + MD5.ToString(), true);
        }




        var sql = "SELECT TOP 1000 MD5, MIN(Score) FROM " + CImageMatching.TABLE_NAME + " GROUP BY MD5 ORDER BY MIN(SCORE), MD5";
        var dt = CConfig.Photos.ExecuteDataSet(sql).Tables[0];
        foreach (DataRow dr in dt.Rows)
        {
            var guid = CAdoData.GetGuid(dr, 0);
            var count = CAdoData.GetInt(dr, 1);
            var name = CUtilities.NameAndCount(CBinary.ToBase64(guid.ToByteArray()).Substring(0, 8).ToUpper(), count);
            CDropdown.Add(ddMatched, name, guid);
        }
        CDropdown.BlankItem(ddMatched, "-- Select Image --");
        CDropdown.SetValue(ddMatched, MD5);

        sql = "SELECT COUNT(DISTINCT MD5) FROM " + CImageMatching.TABLE_NAME;
        int dupes = (int)CConfig.Photos.ExecuteScalar(sql);
        lblCount.Text = CUtilities.CountSummary(dupes / 2, "duplicate");
	}

    protected void Page_Load(object sender, EventArgs e)
    {
		//Last one
		if (Guid.Empty.Equals(MD5))
		{
			if (ddMatched.Items.Count <= 1)
				return;
			if (ddMatched.SelectedIndex + 1 < ddMatched.Items.Count)
			{
				ddMatched.SelectedIndex += 1;
				ddMatched_SelectedIndexChanged(null, null);
			}
            return;
        }

		//Join
        var list = new List<Guid>();
        list.Add(MD5);

		var dict = new Dictionary<Guid, int>();
		Expand(list, dict);

		//No match
        if (list.Count == 1)
        {
            ddMatched.SelectedIndex += 1;
            ddMatched_SelectedIndexChanged(null, null);
            return;
        }

        TableRow tr = null;
        foreach (var i in list)
        {
            if (null == tr || tr.Cells.Count == 5)
            {
                tr = new TableRow();
                tbl.Rows.Add(tr);
            }
			int score = int.MinValue;
			dict.TryGetValue(i, out score);
            Add(tr, i, score);
        }
    }
    private void Expand(List<Guid> list, Dictionary<Guid, int> dict)
    {

        var w = new CCriteriaList(EBoolOperator.Or);
        w.Add("MD5", MD5);
        w.Add("MatchingMD5", MD5);

        var matching = new CImageMatching(CConfig.Photos).SelectWhere(w);

        int added = 0;
        foreach (var i in matching)
        {
            if (!list.Contains(i.MD5))
            {
                list.Add(i.MD5);
				dict.Add(i.MD5, i.Score);
                added++;
            }
            if (!list.Contains(i.MatchingMd5))
            {
                list.Add(i.MatchingMd5);
				dict.Add(i.MatchingMd5, i.Score);
				added++;
            }
        }
        if (added > 0)
            Expand(list, dict);
    }

    private void Add(TableRow tr, Guid md5, int score)
    {
        var td = new TableCell();
        td.VerticalAlign = VerticalAlign.Top;
        tr.Cells.Add(td);

        var ph = CPhotoHash.Cache.GetById(md5);
		if (null == ph)
		{
			var im = new CImageMatching();
			var w = new CCriteriaList(EBoolOperator.Or);
			w.Add("MD5", md5);
			w.Add("MatchingMd5", md5);
			im.DeleteWhere(w);
			return;
		}

        var img = new Image();
        img.ImageUrl = CSitemap.Photo(md5);
        img.Height = new Unit(300);
        img.AlternateText = ph.PhotoCaptions ?? string.Empty;
        td.Controls.Add(img);

        var div = new Panel();
        td.Controls.Add(div);

        var lbl = new Label();
        lbl.Font.Size = new FontUnit(FontSize.Larger);
        lbl.Text += CUtilities.ListToString(ph.MetaTags.Names);
        lbl.Text += "<br/><b>" + ph.Size_ + "</b> (" + ph.PhotoWidth + "x" + ph.PhotoHeight + ")";
        lbl.Text += "<br/>" + CUtilities.Timespan(ph.PhotoCreated);
        lbl.Text += "<br/><b>" + (ph.PhotoFileNames ?? string.Empty).Replace(",", "<br/>").Replace("\r\n", "<br/>") + "</b>";
        lbl.Text += "<br/><b>" + ph.PhotoCaptions + "</b>";
        foreach (var i in ph.Chapters)
            lbl.Text += "<br/>" + CUtilities.Truncate(i.ChapterName, 70);
        if (ph.Chapters.Count == 0)
            lbl.Text += "<br/>&nbsp;";
        lbl.Text += "<br/>&nbsp;";
        div.Controls.Add(lbl);

        var lnk = new HyperLink();
        lnk.Text = "Delete";
        lnk.Font.Size = new FontUnit(FontSize.XLarge);
        lnk.NavigateUrl = "Repeats.aspx?md5=" + CDropdown.GetGuid(ddMatched).ToString() + "&delete=" + md5.ToString();
        //lnk.Visible = MD5 != md5;
        td.Controls.Add(lnk);
        if (MD5 == md5)
        {
            var idx = ddMatched.SelectedIndex;
			if (idx + 1 == ddMatched.Items.Count)
				idx -= 2;
            var next = ddMatched.Items[idx + 1].Value;
            lnk.NavigateUrl = "Repeats.aspx?md5=" + next;
            lnk.Text = "Next Image...";
			lnk.Text = CUtilities.NameAndCount(lnk.Text, score);
        }
        else
        {
            lnk = new HyperLink();
            lnk.Text = CUtilities.NameAndCount("Diff", score);
            lnk.Font.Size = new FontUnit(FontSize.XLarge);
            lnk.NavigateUrl = "Repeats.aspx?md5=" + CDropdown.GetGuid(ddMatched).ToString() + "&different=" + md5.ToString();
            td.Controls.Add(lnk);
            lnk.Style.Add("padding-left", "20px");
        }
    }
    protected void ddMatched_SelectedIndexChanged(object sender, EventArgs e)
    {
		var g = CDropdown.GetGuid(ddMatched);
		if (!Guid.Empty.Equals(g))
			Response.Redirect("Repeats.aspx?md5=" + g.ToString(), true);
    }
}